home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Alles Voor Internet / Tout Pour Internet
/
alles voor internet.iso
/
MacInternet™
/
Telnet
/
NCSA
/
tn3270 2.3d26 source
/
tn3270
/
tcpio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-05-29
|
37KB
|
1,603 lines
/*
* tn3270 for the Macintosh Source Code
* Brown University Computing and Information Services
* Version 2.3d21, January 17, 1991
* Copyright (c) 1988, 1989, 1990, 1991 by Brown University and by
* Peter John DiCamillo.
*
* Permission is granted to any individual or institution to use, copy,
* or redistribute the binary version of this software and its
* documentation provided this notice and the copyright notices are
* retained. Permission is granted to any individual or non-profit
* institution to use, copy, modify, or redistribute the source files
* of this software provided this notice and the copyright notices are
* retained. This software may not be distributed for profit, either
* in original form or in derivative works, nor can the source be
* distributed to other than an individual or a non-profit institution.
* Any individual or group interested in seeing and/or using these
* source files but who are prevented from doing so by the above
* constraints should contact Don Wolfe, Assistant Vice-President for
* Computer Systems at Brown University, (401) 863-7250, for possible
* software licensing of the source developed at Brown.
*
* Brown University and Peter John DiCamillo make no representations
* about the suitability of this software for any purpose.
*
* BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
* EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
* INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#define __SEG__ 3270tcp
#include "maclib.h"
#include "AppleTalk.h"
#include "termdef.h"
#include "globals.h"
#include "kip.h"
#include "netevent.h"
#include "hostform.h"
#define CFIGFILE "NCSA Telnet Settings"
#define HTELNET 23
unsigned char myipnum[4]; /* my IP number */
long kipns; /* name server from KIP */
long mynetmask; /* my network mask */
unsigned char KIPserver[4]; /* AppleTalk address of KIP gateway */
int KIP; /* KIP gateway is present */
int HFS; /* HFS file system being used */
extern int EtherNet; /* "The all-powerful! */
#ifdef TCPDRV
static char KIPzone[33] = "\p*"; /* just to keep the linker happy */
static char *KIPnameptr;
#else
extern char KIPzone[33]; /* zone for KIP from config file */
extern char *KIPnameptr; /* NamesTableEntry pointer for KIP */
#endif
char unldATP; /* flag to unload .ATP driver */
char unldNBP; /* flag to unload NBP */
char dynam; /* myipnum was obtained dynamically */
char snetmask; /* mask was obtained from file */
char kipreg; /* flag to unregister address */
NamesTableEntry myreg; /* my registration entry */
int myport; /* port to close from netopen */
struct machinfo * mp; /* info for machine we connect to */
short savedvol; /* saved volref to restore after configuration */
extern short launchvol; /* default volume when we were launched */
extern int button; /* true if mouse down at startup */
extern char tcpinitok; /* network code is active */
extern char pend_conn; /* connection pending status */
extern char data_init; /* flag for stream parsing */
extern short askedSGA; /* flag for SGA negotiation */
extern char hisopts[]; /* option flags */
extern char myopts[];
extern short telrcv_state; /* FSA state */
extern char sent3270tt;
extern char hadascii;
extern char newserver; /* server supports new protocol */
extern char vmxbgn; /* xfer mode active flag */
extern char vmxsub; /* xfer subset mode active flag */
extern char skiplf; /* lf flag for serscrn */
extern char escmode; /* ESC mode for serscrn */
extern char ftpavail; /* flag for FTP enabled */
extern char tcpinv; /* tcp pending invldscr */
extern short systemvol; /* volume with system files */
extern char sessionhost[]; /* saved name of host we connect to */
extern struct Point sfgpoint; /* SFGetFile location */
extern main(); /* for debugging */
/* for debugging via serial port */
static IOParam pbo; /* serial output parms */
static unsigned char pbchr; /* output character */
unsigned char * wsfbuff; /* buffer for accumulating wsf data */
unsigned char tcphostname[128]; /* cshostname, or prompt response */
extern char serverconn, servermode, serverflags; /* for non-terminal server */
#include "stdio.h"
static unsigned char tcpmsg[256];
static char tcpopnflg = 0;
unsigned char * rcvbuff;
short rcvmax;
short rdportnum();
OSErr NBld();
OSErr nblookup();
OSErr atsend();
OSErr kpdynamip();
OSErr kpregister();
OSErr openatdrv();
OSErr getstr();
tcp_init()
{
long *HFSp= (long *)1014;
char rarp;
Handle version;
short i;
/* version info. for debugging */
strcpy(tcpmsg, "Version string: ");
version = GetResource('GFTM', 0);
if (version != 0) {
i = strlen(tcpmsg);
movmem((*version)+1, tcpmsg+i, (*version)[0]);
tcpmsg[i+(*version)[0]] = 0;
}
else strcpy(tcpmsg, "Version string not available.");
putln(tcpmsg);
strcpy(tcpmsg, "VM file transfer version: ");
version = GetResource('WSFR', 161);
if (version != 0) {
i = strlen(tcpmsg);
movmem((*version)+13, tcpmsg+i, (*version)[12]-1);
tcpmsg[i+(*version)[12]-1] = 0;
while (tcpmsg[i] != 0) {
tcpmsg[i] = ((unsigned char *)(*xtabh))[tcpmsg[i]];
i++;
}
}
else strcpy(tcpmsg, "VM file transfer version unknown.");
putln(tcpmsg);
sprintf(tcpmsg, "main at %lx", main); /* in case we're using a map */
putln(tcpmsg); /* for debugging */
dfltsflg = 2; /* default connection is TCP/IP */
KIP = 0; /* no KIP gateway yet */
HFS = (*HFSp) > 0L; /* check if under HFS */
unldATP = 0; /* haven't loaded ATP */
unldNBP = 0; /* haven't loaded NBP */
kipreg = 0; /* haven't registered our address */
kipns = 0; /* no nameserver from KIP */
tcpinv = 0; /* no pending invldscr call */
pndbeep = 0; /* no pending beep call */
/* allocate buffers */
rcvbuff = (unsigned char *)NewPtr(614L); /* 550 + 64 */
if (rcvbuff == 0L) {
stgalert("tcp rcv buffer", "NewPtr", 614L);
macend();
ExitToShell();
}
rcvmax = 512;
wsfbuff = (unsigned char *)NewPtr(8192L);
if (wsfbuff == 0L) {
stgalert("tcp wsf buffer", "NewPtr", 8192L);
macend();
ExitToShell();
}
/* change name in Apple menu */
SetItem(myMenus[0], 1, "About tn3270...");
/* change names in File menu */
SetItem(myMenus[1], 1, "Open Connection");
SetItem(myMenus[1], 2, "Close Connection");
/* disable function key menu */
DisableItem(myMenus[4], 0);
/* add Network menu */
InsertMenu(myMenus[5], 0);
DrawMenuBar();
/* save current volume, and attempt to find config.tel */
GetVol(tcpmsg, &savedvol);
checkhostfile();
/* initialize and get host information */
ioerror = Snetinit(); /* calls initipnum() */
sprintf(tcpmsg, "return code %d from Snetinit", ioerror);
putln(tcpmsg);
SetVol(0L, savedvol); /* restore initial volume */
if ((ioerror != 0) && (ioerror != -2)) {
ShowAllErrors();
DisposPtr(wsfbuff);
DisposPtr(rcvbuff);
return;
}
tcpinitok = 1; /* remember to shutdown net stuff */
/* if (ioerror == -2) ioerror = reconfigNetwork(); */ /* RARP failed */
if (ioerror != 0) {
ShowAllErrors();
netshut();
tcpinitok = 0;
DisposPtr(wsfbuff);
DisposPtr(rcvbuff);
return;
}
if (EtherNet)
dynam = (myipnum[0] == 'R') && (myipnum[1] == 'A') &&
(myipnum[2] == 'R') && (myipnum[3] == 'P');
netgetip(myipnum); /* get net number, in case RARPed */
netgetmask(&mynetmask); /* mask may have changed too */
ftpavail = Sfmode(); /* get initial FTP settings */
}
int initipnum(dummy)
int dummy; /* used to be "button" */
{
NTElement lkpresult;
BDSType retBDS;
IPGP gateSend, gateRec;
short count, rc;
unsigned char nsaddr[4];
/* open AppleTalk drivers if not using Ethernet */
if (!EtherNet) {
ioerror = openatdrv();
if (ioerror != 0) quit();
/* check for KIP gateway, and if found load number from it */
ioerror = NBld(); /* attempt to load NBP */
if (ioerror != 0) {
stoperr(loadalrt);
quit();
}
/* look for gateway */
rc = nblookup("\p=", "\pIPGATEWAY", KIPzone, &lkpresult, &count);
sprintf(tcpmsg, "rc = %d, count = %d looking for =:IPGATEWAY@%p",
rc, count, KIPzone);
putln(tcpmsg);
if ((rc == 0) && (count > 0)) {
KIP = 1;
movmem(&lkpresult.nteAddress, KIPserver, 4); /* get gateway addr. */
retBDS[0].buffSize = sizeof(gateRec); /* get nameserver address */
retBDS[0].buffPtr = (Ptr)&gateRec;
gateSend.opcode = 3;
rc = atsend(KIPserver, &gateSend, sizeof(struct IPGP), retBDS);
if (rc == 0) { /* got an address */
kipns = gateRec.ipname;
if (kipns != 0) {
Ssetns(&kipns);
movmem(&kipns, nsaddr, 4);
sprintf(tcpmsg,
"Using name server address from gateway: %d.%d.%d.%d",
nsaddr[0], nsaddr[1], nsaddr[2], nsaddr[3]);
putln(tcpmsg);
}
else {
sprintf(tcpmsg,
"Name server address not available from gateway.");
putln(tcpmsg);
}
}
else {
sprintf(tcpmsg, "Return code %d getting nameserver address", rc);
putln(tcpmsg);
}
}
}
else KIP = 0;
ioerror = getipinfo(); /* try to get IP number and mask */
if (button || (ioerror != 0)) {
ioerror = promptip(0); /* get info from user */
if (ioerror != 0) stoperr(cfigalrt); /* report error saving config */
ioerror = getipinfo(); /* try again */
if (ioerror != 0) { /* exit with error if still failed */
stoperr(addralrt);
quit();
}
}
if (KIP) { /* for KIP, need to register number */
ioerror = kpregister(myipnum);
if (ioerror != 0) { /* exit with error if failed */
stoperr(regalrt);
quit();
}
else kipreg = 1;
}
netsetip(myipnum); /* set IP number */
netsetmask(&mynetmask); /* set network mask */
putln("initipnum done");
return(0);
}
getipinfo() /* get IP number and mask */
{
short error, rc;
char strbuf[256];
long dfltmask;
short dfltvol;
mynetmask = 0; /* initialize mask */
dynam = 0; /* no dynamic number yet */
snetmask = 0; /* no mask from file */
/* get IP number */
error = getstr(strbuf, 256, 256);
if (error == 0) error = decodeIPnum(strbuf, myipnum);
if (error) putln("no IP number from resource");
else putln("got IP number from resource");
if (error) {
if (EtherNet) { /* dynamic if Ether and no IP number */
strncpy(myipnum, "RARP", 4);
dynam = 1;
error = 0;
putln("using RARP");
}
else if (KIP) { /* dynamic if KIP and no IP number */
error = kpdynamip(myipnum);
if (!error) {
dynam = 1;
putln("got dynamic IP number");
}
}
}
/* get subnet mask */
if (!error) {
rc = getstr(strbuf, 256, 258);
if (rc == 0) {
if (sscanf(strbuf, "%lx", &mynetmask) != 1)
calcmask(&mynetmask);
else {
calcmask(&dfltmask);
snetmask = (mynetmask != dfltmask);
}
}
else calcmask(&mynetmask);
sprintf(tcpmsg, "net mask = %08lx", mynetmask);
putln(tcpmsg);
}
if (error) {
setmem(myipnum, 4, 0); /* ipnum = 0 if errors */
mynetmask = 0; /* mask too */
putln("error from getipinfo");
}
return(error);
}
promptip(ro)
short ro;
{
DialogPtr dlgptr;
DialogPeek dStorage;
WindowPtr behind;
pascal unsigned short DlgFilter();
unsigned short (*filterProc) ();
short oldHit, itemHit;
short gtype;
Handle iphandle, dynamhandle, maskhandle;
Rect gbox;
unsigned char ipstr[30], maskstr[20], change;
unsigned char tempnum[20];
OSErr rc;
long dfltmask;
short i, rfile;
int hi, low, node;
Size ressize;
Handle temph;
char rarp;
#ifdef TCPDRV
if (ro) showdrv();
return;
#endif
dStorage = 0;
behind = (WindowPtr)-1; /* 272 = r/w, 273 = r/o */
dlgptr = GetNewDialog(272+ro, dStorage, behind);
ctrwindow(dlgptr);
/* get handles to various items */
GetDItem(dlgptr, 3, >ype, &iphandle, &gbox);
GetDItem(dlgptr, 4, >ype, &dynamhandle, &gbox);
GetDItem(dlgptr, 7, >ype, &maskhandle, &gbox);
/* get initial settings */
/* disable dynamic address if AppleTalk and no KIP */
if (!EtherNet && !KIP) HiliteControl(dynamhandle, 255);
/* set ip number radio buttons */
if (!ro) setit(2, dlgptr, (!dynam));
setit(4, dlgptr, dynam && (KIP || EtherNet));
/* set current ip number */
rc = 4;
if (!ro) rc = getstr(ipstr, 30, 256);
if (rc != 0) {
rarp = (myipnum[0] == 'R') && (myipnum[1] == 'A') &&
(myipnum[2] == 'R') && (myipnum[3] == 'P');
if (!rarp) sprintf(ipstr, "%d.%d.%d.%d", myipnum[0], myipnum[1],
myipnum[2], myipnum[3]);
else strcpy(ipstr, "0.0.0.0");
}
SetIText(iphandle, ipstr);
/* set current ip mask */
cvtmask(mynetmask, maskstr);
SetIText(maskhandle, maskstr);
/* set "use subnetting" check box */
setit(5, dlgptr, snetmask);
/* for info. display, get AppleTalk numbers */
if (ro) {
if (EtherNet) hi = low = node = 0;
else getATaddress( &hi, &low, &node);
sprintf(tempnum, "%d.%d", hi, low);
GetDItem(dlgptr, 10, >ype, &temph, &gbox);
SetIText(temph, tempnum);
sprintf(tempnum, "%d", node);
GetDItem(dlgptr, 12, >ype, &temph, &gbox);
SetIText(temph, tempnum);
GetDItem(dlgptr, 13, >ype, &temph, &gbox);
if (EtherNet) SetIText(temph, "[RARP]");
else if (KIP) SetIText(temph, "[KIP]");
}
else {
GetDItem(dlgptr, 9, >ype, &temph, &gbox);
if (EtherNet) SetIText(temph, "[RARP]");
else if (KIP) SetIText(temph, "[KIP]");
}
/* ready to display the dialog */
ShowWindow(dlgptr);
arrowcursor();
/* frame the default selection */
framedflt(dlgptr);
filterProc = DlgFilter;
oldHit = 0;
change = 0;
while(1) {
ModalDialog(filterProc, &itemHit);
if (itemHit != 1) change = 1;
if ((oldHit > 0) && (oldHit != itemHit))
switch(oldHit) {
case 3: /* IP number editText */
GetIText(iphandle, ipstr);
rc = decodeIPnum(ipstr, tempnum);
if (rc) SetIText(iphandle, "0.0.0.0");
break;
case 7: /* mask editText */
GetIText(maskhandle, maskstr);
if (sscanf(maskstr, "%lx", &mynetmask) != 1)
calcmask(&mynetmask);
cvtmask(mynetmask, maskstr);
SetIText(maskhandle, maskstr);
break;
default:
break;
}
oldHit = itemHit;
switch(itemHit) {
case 2: /* IP number buttons */
case 4:
dynam = (itemHit == 4);
setit(2, dlgptr, (!dynam));
setit(4, dlgptr, dynam);
break;
case 5: /* use subnetting box */
snetmask ^= 1;
setit(5, dlgptr, snetmask);
break;
}
if (itemHit == 1) break;
}
/* just return if only "OK" was hit or r/o */
if ((!change) || ro) {
DisposDialog(dlgptr);
return(0);
}
/* set ipstr and maskstr to the text to save */
/* use number unless dynamic specified */
if (dynam) ipstr[0] = 0;
else GetIText(iphandle, ipstr);
/* use mask if subnetting requested */
if (snetmask) GetIText(maskhandle, maskstr);
else maskstr[0] = 0;
/* done with dialog now */
DisposDialog(dlgptr);
/* delete any existing number and mask resources */
sysvol(0);
rfile = OpenResFile(CFIGFILE);
if (rfile != -1) {
temph = GetResource('STR ', 256);
if (temph != 0) if (HomeResFile(temph) == rfile) {
RmveResource(temph);
}
temph = GetResource('STR ', 258);
if (temph != 0) if (HomeResFile(temph) == rfile) {
RmveResource(temph);
}
CloseResFile(rfile);
}
else {
Create(CFIGFILE, 0, 'NCSA', 'IPNO');
CreateResFile(CFIGFILE);
}
/* return if not storing number and mask */
if ((ipstr[0] == 0) && (maskstr[0] == 0)) {
sysvol(1);
return(0);
}
/* get handles to strings to write out */
if (ipstr[0] != 0) {
ctop(ipstr);
ressize = ipstr[0] + 1;
iphandle = NewHandle(ressize);
if (iphandle == 0) {
sysvol(1);
return(1);
}
movmem(ipstr, (*iphandle), ipstr[0]+1);
}
else iphandle = 0;
if (maskstr[0] != 0) {
ctop(maskstr);
ressize = maskstr[0] + 1;
maskhandle = NewHandle(ressize);
if (maskhandle == 0) {
if (iphandle != 0) DisposHandle(iphandle);
sysvol(1);
return(2);
}
movmem(maskstr, (*maskhandle), maskstr[0]+1);
}
else maskhandle = 0;
/* write the required resources */
rfile = OpenResFile(CFIGFILE);
if ((ResError() == 0) && (iphandle != 0))
AddResource(iphandle, 'STR ', 256, "IP Number");
if ((ResError() == 0) && (maskhandle != 0))
AddResource(maskhandle, 'STR ', 258, "Network Mask");
rc = ResError();
if (rfile != -1) CloseResFile(rfile);
if (rc == 0) rc = ResError();
sysvol(1);
return(rc);
}
updhostrsc(s) /* store new default host name */
char * s;
{
short rfile;
Handle temph;
Size ressize;
/* delete any existing host resource */
sysvol(0);
rfile = OpenResFile(CFIGFILE);
if (rfile != -1) {
temph = GetResource('STR ', 257);
if (temph != 0) if (HomeResFile(temph) == rfile) {
RmveResource(temph);
}
CloseResFile(rfile);
}
else {
Create(CFIGFILE, 0, 'NCSA', 'IPNO');
CreateResFile(CFIGFILE);
}
/* return if not storing host name */
if (s[0] == 0) {
sysvol(1);
return;
}
/* get handles to string to write out */
ctop(s);
ressize = s[0] + 1;
temph = NewHandle(ressize);
if (temph == 0) {
sysvol(1);
return;
}
movmem(s, (*temph), s[0]+1);
/* write the required resource */
rfile = OpenResFile(CFIGFILE);
if ((ResError() == 0) && (temph != 0))
AddResource(temph, 'STR ', 257, "Default Host");
if (rfile != -1) CloseResFile(rfile);
sysvol(1);
return;
}
showdrv()
{
DialogPtr dlgptr;
DialogPeek dStorage;
WindowPtr behind;
pascal unsigned short DlgFilter();
unsigned short (*filterProc) ();
short itemHit;
short gtype;
Handle iphandle;
Rect gbox;
unsigned char ipstr[30];
dStorage = 0;
behind = (WindowPtr)-1;
dlgptr = GetNewDialog(280, dStorage, behind);
ctrwindow(dlgptr);
GetDItem(dlgptr, 4, >ype, &iphandle, &gbox);
sprintf(ipstr, "%d.%d.%d.%d", myipnum[0], myipnum[1],
myipnum[2], myipnum[3]);
SetIText(iphandle, ipstr);
/* ready to display the dialog */
ShowWindow(dlgptr);
arrowcursor();
/* frame the default selection */
framedflt(dlgptr);
/* show dialog */
filterProc = DlgFilter;
ModalDialog(filterProc, &itemHit);
DisposDialog(dlgptr);
return(0);
}
calcmask(mask) /* calculate mask from IP number */
long * mask;
{
if (!(myipnum[0] & 0x80))
(*mask) = 0xff000000; /* Class A */
else if ((myipnum[0] & 0xc0) == 0x80)
(*mask) = 0xffff0000; /* Class B */
else
(*mask) = 0xffffff00; /* Class C */
}
tcpdflthost(s)
char * s;
{
short rc;
rc = getstr(s, 128, 257);
if (rc != 0) strcpy(s, "?"); /* If "?", prompt will be issued */
}
long tcpgetrsrv(init)
char init;
{
#ifdef TCPDRV
if (init) return(131072);
else {
if (online) return(20480);
else return(40960);
}
#else
if (init) return(135168);
else {
return(26624);
}
#endif
}
tcplgin()
{
struct machinfo *Sgethost();
short i;
OSErr rc, hostdlg();
/* attempt to get host name or address for this session */
if (apiopen && (apihostname[0] != 0)) {
strcpy(tcphostname, apihostname);
}
else {
strcpy(tcphostname, cshostname);
}
if (strcmp(tcphostname, "?") == 0) {
strcpy(tcphostname, ""); /* initial value for hostdlg */
rc = hostdlg(tcphostname);
if (rc != noErr) return;
}
strcpy(sessionhost, tcphostname); /* host name for this session */
for (i=0; i < 128; i++) {
if (sessionhost[i] == '\0') break;
if (sessionhost[i] == ':') {
sessionhost[i] = '\0';
break;
}
}
xfrst(); /* reset file transfer status */
rbsize = 0;
kblock = 1; /* initialize status line variables */
kblcode = 2;
ioerror = 0;
data_init = 1; /* first data byte will begin write */
askedSGA = 0; /* haven't negotiated SGA yet */
setmem(hisopts, 256, 0); /* initialize option flags */
setmem(myopts, 256, 0);
telrcv_state = 0; /* initialize FSA */
sent3270tt = 0; /* haven't sent 3270 terminal type */
hadascii = 0; /* no ascii data yet */
newserver = 0; /* assume not new server */
skiplf = 0; /* reset line mode flags */
escmode = 0;
/* attempt to get IP address for host */
mp = Sgethost(sessionhost);
ShowAllErrors();
if (!mp) { /* table lookup failed; try name server */
myport = Sdomain(sessionhost);
sprintf(tcpmsg, "return code %d from Sdomain for %s",
myport, sessionhost);
putln(tcpmsg);
if (myport == -1) {
stoperr(domalrt);
kblcode = 4;
if (apiopen) {
apiopenerr(openResFailed);
}
}
else pend_conn = 1;
}
else { /* try to open a connection */
myport = Snetopen(mp, rdportnum());
if (myport < 0) {
stoperr(topnalrt);
kblcode = 4;
if (apiopen) {
apiopenerr(openConnFailed);
}
}
else pend_conn = 2;
}
}
tcplgout()
{
if (apiopenpend) apiopenerr(openConnFailed);
apiopen = 0;
if ((pend_conn > 0) || (logon)) netclose(myport);
ftpcopen = ftpdopen = ftplopen = 0; /* no TCP/IP FTP yet */
pend_conn = 0;
online = logon = 0;
kbqsize = 0;
kblock = 1;
if (kblcode != 3) kblcode = 4;
if (myWindow != 0) {
closeresponse(closeUnknown);
newstat();
removewindow();
apideregister(1); /* deregister session */
}
DisableItem(myMenus[4], 0);
DrawMenuBar();
}
tcp_end()
{
if (apiopenpend) apiopenerr(openConnFailed);
apiopen = 0;
if ((pend_conn > 0) || (logon)) {
netclose(myport);
pend_conn = 0;
logon = 0;
}
if (kipreg) {
kpunregister(); /* un-register our address */
kipreg = 0;
}
if (tcpinitok) {
netshut(); /* undo Snetinit */
tcpinitok = 0;
}
NBuld(); /* unload NBP */
ATuld(); /* unload ATP */
DisposPtr(wsfbuff);
DisposPtr(rcvbuff);
}
/* tcpwrite - call netwrite to get all data written */
tcpwrite(dptr, dsize)
unsigned char * dptr;
short dsize;
{
short cnt;
static unsigned long * Ticks = (unsigned long *)0x16a;
unsigned long limit;
online = 0;
newstat();
limit = (*Ticks) + 60 * cs.timeout * cs.retries;
while (dsize > 0) {
if (cs.dblevel > 2) tcpdump("netwrite", dptr, dsize);
netpush(myport);
cnt = netwrite(myport, dptr, dsize);
if (cs.dblevel > 2) {
sprintf(tcpmsg, "netwrite wrote %d bytes", cnt);
putln(tcpmsg);
}
if (cnt > 0) {
dptr += cnt;
dsize -= cnt;
limit = (*Ticks) + 60 * cs.timeout * cs.retries;
}
myStask();
if ((*Ticks) > limit) {
kblcode = 3;
ioerror = 4;
closeresponse(closeNetFail);
tcplgout();
stoperr(wrtalrt);
return;
}
}
online = 1;
newstat();
}
tcpin(asc, chr, shift)
unsigned char asc, chr, shift;
{
if (!logon) { /* Return or CLEAR for new session, else beep */
if (pend_conn == 0) kbnew(chr, shift);
else if ((pend_conn == 3) && (!kblock)) tcpkbin(asc, chr, shift);
else beep();
return;
}
if (chr == 196) { /* perform program reset immediately */
tcp_reset();
xfrst();
invldscr();
return;
}
if (chr == 185) { /* perform keyboard immediately */
hndkbd(chr, shift);
return;
}
if ((kbqsize == KBQMAX) || (vmxbgn && (!vmxsub))) {
beep(); /* error if xfer mode or queue full */
kerr(3);
}
else { /* else add to keyboard queue */
kbqueue[kbqsize].code = chr;
kbqueue[kbqsize].shift = shift;
kbqsize++;
}
}
tcp_reset()
{
if (logon) {
kblock = kblcode = 0;
online = 1;
}
lastwcc = 0x02;
kb_err = 0;
kbqsize = 0;
aplmode = insmode = 0;
fixbracket = cs.std_brack && (!aplmode) && (stdfont != ALAFONT);
newstat();
}
ATuld() /* if necessary, unload .ATP driver */
{
CntrlParam cp;
if (sw_active() || (!unldATP)) return;
unldATP = 0;
cp.ioCRefNum = -11; /* .ATP reference number */
PBClose(&cp, 0);
}
OSErr NBld() /* load NBP */
{
CntrlParam cp;
OSErr rc;
if (unldNBP) return(0);
cp.ioCRefNum = -10; /* .MPP driver number */
cp.csCode = 249;
rc = PBControl(&cp, 0);
if (rc == 0) unldNBP = 1;
return(rc);
}
NBuld() /* unload NBP */
{
CntrlParam cp;
if (!unldNBP) return;
cp.ioCRefNum = -10; /* .MPP driver number */
cp.csCode = 255;
PBControl(&cp, 0);
unldNBP = 0;
}
OSErr nblookup(object, type, zone, result, count)
char * object, * type, * zone;
NTElement * result;
short * count;
{
MPPParamBlock Mpb;
OSErr rc;
char entity[99];
NBPSetEntity(entity, object, type, zone);
Mpb.NBPinterval = 3;
Mpb.NBPcount = 4;
Mpb.NBPentityPtr = entity;
Mpb.NBPretBuffPtr = (Ptr)result;
Mpb.NBPretBuffSize = sizeof(NTElement);
Mpb.NBPmaxToGet = 1;
Mpb.MPPioRefNum = -10; /* .MPP driver number */
Mpb.MPPcsCode = 251; /* lookup name */
rc = PBControl(&Mpb, 0);
(*count) = Mpb.NBPnumGotten;
return(rc);
}
OSErr atsend(ablock, sendaddr, sendlen, retbds)
AddrBlock * ablock;
char * sendaddr;
short sendlen;
BDSPtr retbds;
{
ATPParamBlock Apb;
OSErr rc;
Apb.ATPuserData = 0;
Apb.ATPcsCode = 255;
Apb.ATPioRefNum = -11;
Apb.ATPatpFlags = 0;
Apb.ATPaddrBlock = (*ablock);
Apb.ATPreqLength = sendlen;
Apb.ATPreqPointer = sendaddr;
Apb.ATPbdsPointer = (Ptr)retbds;
Apb.ATPnumOfBuffs = 1;
Apb.ATPtimeOutVal = cs.timeout;
Apb.ATPretryCount = cs.retries;
rc = PBControl(&Apb, 0);
return(rc);
}
OSErr kpdynamip(ipnum)
long * ipnum;
{
IPGP gateRec, gateSend;
BDSType retBDS;
OSErr rc;
putln("obtaining dynamic IP number");
retBDS[0].buffSize = sizeof(gateRec);
retBDS[0].buffPtr = (Ptr)&gateRec;
gateSend.opcode = 1;
rc = atsend(KIPserver, &gateSend, sizeof(struct IPGP), retBDS);
if (rc != 0) return(rc);
(*ipnum) = gateRec.ipaddress;
return(0);
}
OSErr kpregister(ipnum)
unsigned char * ipnum;
{
MPPParamBlock Mpb;
OSErr rc;
char temps[20];
sprintf(temps, "%d.%d.%d.%d", ipnum[0], ipnum[1], ipnum[2], ipnum[3]);
sprintf(tcpmsg, "registering %s", temps);
putln(tcpmsg);
ctop(temps);
if (KIPnameptr) kpunregister();
KIPnameptr = &myreg;
setmem(&myreg, sizeof(NamesTableEntry), 0);
NBPSetNTE(&myreg, temps, "\pIPADDRESS", KIPzone, 72);
Mpb.MPPioRefNum = -10;
Mpb.MPPcsCode = 253;
Mpb.NBPinterval = 5;
Mpb.NBPcount = 5;
Mpb.NBPntQElPtr = (Ptr)&myreg;
Mpb.NBPverifyFlag = 1;
rc = PBControl(&Mpb, 0);
sprintf(tcpmsg, "rc = %d from NBPRegister", rc);
putln(tcpmsg);
return(rc);
}
kpunregister()
{
MPPParamBlock Mpb;
OSErr rc;
Mpb.MPPioRefNum = -10;
Mpb.MPPcsCode = 252;
Mpb.NBPentityPtr = (Ptr)myreg.nt.entityData;
rc = PBControl(&Mpb, 0);
KIPnameptr = 0;
sprintf(tcpmsg, "rc = %d from NBPRemove", rc);
putln(tcpmsg);
}
putln (s) /* put message in error log */
char * s;
{
static FILE *fp = 0;
static char debugfile[] = "Ram:tcpdebug";
short fref, i;
long count;
static int rc;
if (!cs.dblevel) return;
if (cs.dblevel == 99) {
if (!tcpopnflg) {
rc = seropen();
tcpopnflg = 1;
}
if (rc != 0) return;
count = strlen(s);
if (count > 0)
for (i = 0; i < count; i++) {
rc = serchr(s[i]);
myStask();
if (rc != 0) break;
}
if (rc == 0) rc = serchr('\015');
if (rc == 0) rc = serchr('\012');
dbgwait();
}
else {
if (!tcpopnflg) {
FSDelete(debugfile, 0);
Create(debugfile, 0, 'MPS ', 'TEXT');
tcpopnflg = 1;
}
if (FSOpen(debugfile, 0, &fref) != 0) return;
SetFPos(fref, fsFromLEOF, 0L);
count = strlen(s);
if (count > 0) FSWrite(fref, &count, s);
count = 1;
FSWrite(fref, &count, "\015");
FSClose(fref);
FlushVol("Ram", 0);
}
}
seropen()
{
int i;
char * x;
static char aoutname[8];
RAMSDOpen(sPortA);
x = (char *)&pbo;
for (i=0; i < sizeof(pbo); i++) {
x[i] = 0;
}
strcpy(aoutname, ".AOut");
ctop(aoutname);
pbo.ioNamePtr = (StringPtr)aoutname;
pbo.ioRefNum = -7;
pbo.ioVersNum = 0;
pbo.ioPermssn = fsWrPerm;
pbo.ioMisc = 0;
pbo.ioBuffer = (Ptr)&pbchr;
pbo.ioReqCount = 1;
pbo.ioPosMode = 0;
pbo.ioPosOffset = 0;
return(0);
}
serchr(c)
unsigned char c;
{
pbchr = c;
return(PBWrite(&pbo, 0));
}
OSErr openatdrv() /* open AppleTalk drivers */
{
static unsigned char *SPConfig = (unsigned char *)0x1fb;
static unsigned char *PortBUse = (unsigned char *)0x291;
IOParam openblk;
OSErr rc;
if ((*PortBUse & 0x80) == 0x80) { /* check if port B is in use */
/* port B not in use: */
if ((*SPConfig & 0x0f) > 1) { /* error unless unconfigured */
stoperr(portalrt); /* or configured for AppleTalk */
return(-98);
}
else { /* else open MPP driver */
openblk.ioPermssn = 0;
openblk.ioNamePtr = (StringPtr)"\p.MPP";
rc = PBOpen(&openblk, 0);
if (rc != 0) {
stoperr(loadalrt);
return(rc);
}
}
}
else { /* port B in use: */
if ((*PortBUse & 0x0f) != 1) { /* error if not in use by */
stoperr(portalrt); /* AppleTalk */
return(-97);
}
}
/* load ATP if not already loaded */
if ((*PortBUse & 0x10) == 0) {
openblk.ioPermssn = 0;
openblk.ioNamePtr = (StringPtr)"\p.ATP";
rc = PBOpen(&openblk, 0);
if (rc != 0) {
stoperr(loadalrt);
return(rc);
}
unldATP = 1; /* remember we loaded .ATP */
}
return(0);
}
isHFS()
{
return(HFS);
}
cvtmask(mask, s)
long mask;
char * s;
{
register short i, len;
sprintf(s, "%08lx", mask);
len = strlen(s);
for (i=0; i < len; i++)
s[i] = toupper(s[i]);
}
decodeIPnum( s, myipnum)
char *s;
unsigned char *myipnum;
{
short i;
int node, hi, low;
char temp[50];
char addrflag;
for (i=0; i<4; i++) myipnum[i]=0;
i=0;
addrflag = 0;
while((*s) && (i<4) ) {
switch( *s) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
myipnum[i]= myipnum[i] *10 + (*s-'0');
break;
case '.':
i++;
break;
case 'H':
case 'h':
if (addrflag == 0) {
getATaddress( &hi, &low, &node);
addrflag = 1;
}
myipnum[i]=hi;
break;
case 'L':
case 'l':
if (addrflag == 0) {
getATaddress( &hi, &low, &node);
addrflag = 1;
}
myipnum[i]=low;
break;
case 'N':
case 'n':
if (addrflag == 0) {
getATaddress( &hi, &low, &node);
addrflag = 1;
}
myipnum[i]=node;
break;
default:
break;
}
s++;
}
sprintf( temp," IPNUM= %d.%d.%d.%d", (int) myipnum[0], (int) myipnum[1], (int) myipnum[2],
(int) myipnum[3]);
putln(temp);
if (i<3) return( 1);
else return( 0);
}
ShowAllErrors()
{
int ev, what, dat;
ev = Sgetevent( ERRCLASS,&what,&dat);
while (ev) {
NetError(dat);
ev = Sgetevent( ERRCLASS,&what,&dat);
}
}
NetError(code)
int code;
{
char buffer1[100],buffer2[100], *neterrstring();
int ev, what;
short class,dItem;
pascal unsigned short DlgFilter();
unsigned short (*filterProc) ();
static char nullstr[1] = {0};
buffer1[0]=0;
buffer2[0]=0;
if (code<0) {
strncpy( buffer2, neterrstring(code), 99);
ev = Sgetevent( ERRCLASS,&what,&code);
if (ev)
strncpy( buffer1, neterrstring(code), 99);
}
else
strncpy( buffer1, neterrstring(code), 99);
class = code/100;
if ((code == 402) || (code == 405)) class = 5;
if ((class==1 || class==5 || class==9) && (code!=503) ) {
/* Ok, I'll show the user these */
ParamText( buffer1, buffer2, nullstr, nullstr);
filterProc = DlgFilter;
arrowcursor();
if (class == 9) StopAlert(274, filterProc);
else if (class == 5) CautionAlert(275, filterProc);
else NoteAlert(276, filterProc);
ParamText(nullstr, nullstr, nullstr, nullstr);
}
if (buffer1[0])
putln(buffer1);
if (buffer2[0])
putln(buffer2);
}
tcpinfo()
{
DialogPtr dlgptr;
DialogPeek dStorage;
WindowPtr behind;
short gtype, itemHit;
Rect gbox;
pascal unsigned short DlgFilter();
unsigned short (*filterProc) ();
Handle hosth, iph, stath;
char ipstr[20];
dStorage = 0;
behind = (WindowPtr)-1;
dlgptr = GetNewDialog(277, dStorage, behind);
ctrwindow(dlgptr);
/* get handles we will need */
GetDItem(dlgptr, 3, >ype, &hosth, &gbox);
GetDItem(dlgptr, 5, >ype, &iph, &gbox);
GetDItem(dlgptr, 7, >ype, &stath, &gbox);
/* set host name */
if (pend_conn == 1) SetIText(hosth, sessionhost);
else if (mp->hname == 0) {
if (mp->sname == 0) SetIText(hosth, "unknown");
else if (strcmp(mp->sname, "default") == 0) SetIText(hosth, "unknown");
else SetIText(hosth, mp->sname);
}
else SetIText(hosth, mp->hname);
/* set ip number */
if (pend_conn == 1) SetIText(iph, "unknown");
else {
sprintf(ipstr, "%d.%d.%d.%d", mp->hostip[0],
mp->hostip[1], mp->hostip[2], mp->hostip[3]);
SetIText(iph, ipstr);
}
/* set status */
switch (pend_conn) {
case 0: /* if 0, must be logged on */
SetIText(stath, "3270 session established");
break;
case 1: /* waiting for name server */
SetIText(stath, "waiting for response from name server");
break;
case 2: /* waiting for connection */
SetIText(stath, "waiting for connection to complete");
break;
case 3: /* negotiating settings */
if (hadascii) SetIText(stath, "connected in line mode");
else SetIText(stath, "connected: negotiating settings");
break;
default: /* shouldn't happen */
break;
}
/* ready to display the dialog */
ShowWindow(dlgptr);
arrowcursor();
/* frame the default selection */
framedflt(dlgptr);
/* display the dialog until OK selected */
filterProc = DlgFilter;
itemHit = 0;
while (itemHit != 1) ModalDialog(filterProc, &itemHit);
DisposDialog(dlgptr);
}
int tcp_session() /* return TRUE if session active */
{
return(logon || (hadascii && (pend_conn == 3)));
}
short rdportnum() /* return port number from tcphostname, or default */
{
register short i, count, len, port;
register char * s;
len = strlen(tcphostname);
if (len < 3) return(HTELNET); /* need at least two colons and digit */
count = 0;
for (i=0; i < len; i++) {
if (tcphostname[i] == ':') count++;
if (count == 2) break;
}
if (count < 2) return(HTELNET);
s = tcphostname + i + 1; /* s = host number string */
if (s[0] == '\0') return(HTELNET);
if ((strcmp(s, "IRC") == 0) || (strcmp(s, "irc") == 0)) {
serverconn = 1;
servermode = 0;
serverflags = 1;
port = 6667;
}
else if ((strcmp(s, "SMTP") == 0) || (strcmp(s, "smtp") == 0)) {
serverconn = 1;
servermode = 0;
serverflags = 0;
port = 25;
}
else if ((strncmp(s, "SERVER=", 7) == 0) || (strncmp(s, "server=", 7) == 0)) {
serverconn = 1;
servermode = 0;
serverflags = 0;
port = atoi(s+7);
}
else {
serverconn = servermode = serverflags = 0;
port = atoi(s);
}
if (port == 0) {
sprintf(tcpmsg, "Port specification %s is invalid", s);
putln(tcpmsg);
stoperr(pnumalrt);
port = HTELNET;
}
if (serverconn) {
sprintf(tcpmsg, "Using non-Telnet connection mode");
putln(tcpmsg);
}
sprintf(tcpmsg, "port number = %d", port);
putln(tcpmsg);
return(port);
}
printf(s)
char * s;
{
putln(s);
}
tcpdump(msg, data, len)
unsigned char *msg, *data;
short len;
{
short count, i, j;
unsigned char tcpchar[66];
sprintf(tcpmsg, "%s: %d bytes:", msg, len);
putln(tcpmsg);
count = 0;
tcpmsg[0] = 0;
tcpchar[0] = 0;
for (i=0; i < len; i++) {
j = strlen(tcpmsg);
sprintf(tcpmsg+j, "%02x", data[i]);
if (xtabh != 0) {
j = strlen(tcpchar);
if (nl_handle != 0) {
sprintf(tcpchar+j, "%c ", (*xtabh)[nltab[data[i]]]);
}
else {
sprintf(tcpchar+j, "%c ", (*xtabh)[data[i]]);
}
}
count++;
if (count == 32) {
putln(tcpmsg);
if (xtabh != 0) putln(tcpchar);
tcpmsg[0] = 0;
tcpchar[0] = 0;
count = 0;
}
}
if (strlen(tcpmsg) > 0) putln(tcpmsg);
if ((strlen(tcpchar) > 0) && (xtabh != 0)) putln(tcpchar);
putln("");
}
dbgwait()
{
static unsigned long *Ticks = (unsigned long *)0x16a;
unsigned long limit;
limit = (*Ticks) + 15;
while (limit > (*Ticks)) myStask();
}
OSErr getstr(s, lim, num)
char * s;
short lim, num;
{
short rfile, rc;
Handle temph;
unsigned char * tempp;
sysvol(0);
rfile = OpenResFile(CFIGFILE);
if (rfile != -1) {
temph = GetResource('STR ', num);
if (temph != 0) if (HomeResFile(temph) == rfile) {
tempp = *temph;
if (tempp[0] > lim-1) rc = 12;
else {
movmem(tempp, s, tempp[0]+1);
ptoc(s);
sprintf(tcpmsg, "STR %d = \"%s\"", num, s);
putln(tcpmsg);
rc = 0;
}
}
else rc = 8;
CloseResFile(rfile);
}
else rc = 4;
sysvol(1);
sprintf(tcpmsg, "getstr rc = %d for STR %d", rc, num);
putln(tcpmsg);
return(rc);
}
sysvol(reset)
short reset;
{
char strbuff[256];
static short dfltvol;
if (reset) SetVol(0L, dfltvol);
else {
GetVol(strbuff, &dfltvol);
SetVol(0L, systemvol);
}
}
tcpquit(rc)
OSErr rc;
{
/* error "rc" from opening MacTCP */
sprintf(tcpmsg, "Unable to open MacTCP. Result code = %d.", rc);
stopterr(tcpmsg);
quit();
}
quit()
{
if ((pend_conn > 0) || (logon)) {
netclose(myport);
pend_conn = 0;
logon = 0;
}
if (kipreg) {
kpunregister(); /* un-register our address */
kipreg = 0;
}
if (tcpinitok) {
netshut(); /* undo Snetinit */
tcpinitok = 0;
}
NBuld(); /* unload NBP */
ATuld(); /* unload ATP */
DisposPtr(wsfbuff);
DisposPtr(rcvbuff);
macend();
ExitToShell();
}
DisplayMacBinary()
{
}
checkhostfile()
{
OSErr rc, fsrdopen();
short fnum;
Point where;
ProcPtr fileFilter, dlgHook;
short numTypes;
SFTypeList typeList;
SFReply reply;
char hostfile[12];
strcpy(hostfile, "config.tel");
rc = fsrdopen(hostfile, savedvol, &fnum);
if (rc == 0) {
FSClose(fnum);
return;
}
/* couldn't find the file on the default volume, so try the launch volume */
SetVol(0L, launchvol);
rc = fsrdopen(hostfile, launchvol, &fnum);
if (rc == 0) {
FSClose(fnum);
return;
}
/* now try the system volume */
SetVol(0L, systemvol);
rc = fsrdopen(hostfile, systemvol, &fnum);
if (rc == 0) {
FSClose(fnum);
return;
}
/* finally, allow the user to locate it */
SetVol(0L, savedvol);
note_err(hostfalrt); /* tell users what to do with SFGetFile */
where = sfgpoint;
fileFilter = dlgHook = 0;
numTypes = 1;
typeList[0] = 'TEXT';
dlgHook = 0;
arrowcursor();
SFGetFile(&where, "Select the file \"config.tel\":", fileFilter,
numTypes, typeList, dlgHook, &reply);
if (reply.good == 0) return;
SetVol(0L, reply.vRefNum);
}